<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/limh/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/limh/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/limh/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/limh/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/limh/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/limh/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/limh/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="教程,">










<meta name="description" content="DS18B20 是美信公司的一款温度传感器，单片机可以通过 1-Wire 协议与 DS18B20 进行通信，最终将温度读出。1-Wire 总线的硬件接口很简单，只需要把 DS18B20 的数据引脚和单片机的一个 IO 口接上就可以了。硬件的简单，随之而来的，就是软件时序的复杂。1-Wire总线的时序比较复杂，很多同学在这里独立看时序图都看不明白，所以这里还要带着大家来研究 DS18B20 的时序图">
<meta name="keywords" content="教程">
<meta property="og:type" content="article">
<meta property="og:title" content="16.4、温度传感器DS18B20">
<meta property="og:url" content="https://tdnr.gitee.io/limh/2014/12/01/mcu109/index.html">
<meta property="og:site_name" content="土逗牛肉">
<meta property="og:description" content="DS18B20 是美信公司的一款温度传感器，单片机可以通过 1-Wire 协议与 DS18B20 进行通信，最终将温度读出。1-Wire 总线的硬件接口很简单，只需要把 DS18B20 的数据引脚和单片机的一个 IO 口接上就可以了。硬件的简单，随之而来的，就是软件时序的复杂。1-Wire总线的时序比较复杂，很多同学在这里独立看时序图都看不明白，所以这里还要带着大家来研究 DS18B20 的时序图">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-140323230233592.png">
<meta property="og:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323032L26.png">
<meta property="og:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-140323230431910.png">
<meta property="og:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-1403232306149C.png">
<meta property="og:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323110U45.png">
<meta property="og:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323121O24.png">
<meta property="og:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323163AN.png">
<meta property="og:updated_time" content="2019-01-31T13:14:53.367Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="16.4、温度传感器DS18B20">
<meta name="twitter:description" content="DS18B20 是美信公司的一款温度传感器，单片机可以通过 1-Wire 协议与 DS18B20 进行通信，最终将温度读出。1-Wire 总线的硬件接口很简单，只需要把 DS18B20 的数据引脚和单片机的一个 IO 口接上就可以了。硬件的简单，随之而来的，就是软件时序的复杂。1-Wire总线的时序比较复杂，很多同学在这里独立看时序图都看不明白，所以这里还要带着大家来研究 DS18B20 的时序图">
<meta name="twitter:image" content="http://c.biancheng.net/cpp/uploads/allimg/140323/1-140323230233592.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/limh/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://tdnr.gitee.io/limh/2014/12/01/mcu109/">





  <title>16.4、温度传感器DS18B20 | 土逗牛肉</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans ">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/limh/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">土逗牛肉</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/limh/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br>
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/limh/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/limh/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/limh/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br>
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/limh/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br>
            
            关于
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://tdnr.gitee.io/limh/limh/2014/12/01/mcu109/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="土逗牛肉">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/limh/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="土逗牛肉">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">16.4、温度传感器DS18B20</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-12-01T20:41:09+08:00">
                2014-12-01
              </time>
            

            

            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/limh/categories/单片机教程/" itemprop="url" rel="index">
                    <span itemprop="name">单片机教程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>DS18B20 是美信公司的一款温度传感器，单片机可以通过 1-Wire 协议与 DS18B20 进行通信，最终将温度读出。1-Wire 总线的硬件接口很简单，只需要把 DS18B20 的数据引脚和单片机的一个 IO 口接上就可以了。硬件的简单，随之而来的，就是软件时序的复杂。1-Wire总线的时序比较复杂，很多同学在这里独立看时序图都看不明白，所以这里还要带着大家来研究 DS18B20 的时序图。我们先来看一下 DS18B20 的硬件原理图，如图 16-12 所示。</p>
<p><img src="http://c.biancheng.net/cpp/uploads/allimg/140323/1-140323230233592.png" alt></p>
<center><strong>图 16-12  DS18B20 电路原理图</strong></center>

<p>DS18B20 通过编程，可以实现最高 12 位的温度存储值，在寄存器中，以补码的格式存储，如图 16-13 所示。</p>
<p><img src="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323032L26.png" alt></p>
<center><strong>图 16-13  DS18B20 温度数据格式</strong></center>

<p>一共 2 个字节，LSB 是低字节，MSB 是高字节，其中 MSb 是字节的高位，LSb 是字节的低位。大家可以看出来，二进制数字，每一位代表的温度的含义，都表示出来了。其中 S表示的是符号位，低 11 位都是 2 的幂，用来表示最终的温度。DS18B20 的温度测量范围是从-55 度到+125 度，而温度数据的表现形式，有正负温度，寄存器中每个数字如同卡尺的刻度一样分布，如图 16-14 所示。</p>
<p><img src="http://c.biancheng.net/cpp/uploads/allimg/140323/1-140323230431910.png" alt></p>
<center><strong>图 16-14  DS18B20 温度值</strong></center>

<p>二进制数字最低位变化 1，代表温度变化 0.0625 度的映射关系。当 0 度的时候，那就是0x0000，当温度 125 度的时候，对应十六进制是 0x07D0，当温度是零下 55 度的时候，对应的数字是 0xFC90。反过来说，当数字是 0x0001 的时候，那温度就是 0.0625 度了。</p>
<p>首先，我先根据手册上 DS18B20 工作协议过程大概讲解一下。</p>
<h3 id="1-初始化"><a href="#1-初始化" class="headerlink" title="1) 初始化"></a>1) 初始化</h3><p>和 I2C 的寻址类似，1-Wire 总线开始也需要检测这条总线上是否存在 DS18B20这个器件。如果这条总线上存在 DS18B20，总线会根据时序要求返回一个低电平脉冲，如果不存在的话，也就不会返回脉冲，即总线保持为高电平，所以习惯上称之为检测存在脉冲。此外，获取存在脉冲不仅仅是检测是否存在 DS18B20，还要通过这个脉冲过程通知 DS18B20准备好，单片机要对它进行操作了，如图 16-15 所示。</p>
<p><img src="http://c.biancheng.net/cpp/uploads/allimg/140323/1-1403232306149C.png" alt></p>
<center><strong>图16-15  检测存在脉冲</strong></center>

<p>大家注意看图，实粗线是我们的单片机 IO 口拉低这个引脚，虚粗线是 DS18B20 拉低这个引脚，细线是单片机和 DS18B20 释放总线后，依靠上拉电阻的作用把 IO 口引脚拉上去。这个我们前边提到过了，51 单片机释放总线就是给高电平。</p>
<p>存在脉冲检测过程，首先单片机要拉低这个引脚，持续大概 480us 到 960us 之间的时间即可，我们的程序中持续了 500us。然后，单片机释放总线，就是给高电平，DS18B20 等待大概 15 到 60us 后，会主动拉低这个引脚大概是 60 到 240us，而后 DS18B20 会主动释放总线，这样 IO 口会被上拉电阻自动拉高。</p>
<p>有的同学还是不能够彻底理解，程序列出来逐句解释。首先，由于 DS18B20 时序要求非常严格，所以在操作时序的时候，为了防止中断干扰总线时序，先关闭总中断。然后第一步，拉低 DS18B20 这个引脚，持续 500us；第二步，延时 60us；第三步，读取存在脉冲，并且等待存在脉冲结束。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">bit Get18B20Ack()&#123;</span><br><span class="line">    bit ack;</span><br><span class="line">    EA = 0; //禁止总中断</span><br><span class="line">    IO_18B20 = 0; //产生 500us 复位脉冲</span><br><span class="line">    DelayX10us(50);</span><br><span class="line">    IO_18B20 = 1;</span><br><span class="line">    DelayX10us(6); //延时 60us</span><br><span class="line">    ack = IO_18B20; //读取存在脉冲</span><br><span class="line">    while(!IO_18B20); //等待存在脉冲结束</span><br><span class="line">    EA = 1; //重新使能总中断</span><br><span class="line">    return ack;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>很多同学对第二步不理解，时序图上明明是 DS18B20 等待 15us 到 60us，为什么要延时60us 呢？举个例子，妈妈在做饭，告诉你大概 5 分钟到 10 分钟饭就可以吃了，那么我们什么时候去吃，能够绝对保证吃上饭呢？很明显，10 分钟以后去吃肯定可以吃上饭。同样的道理，DS18B20 等待大概是 15us 到 60us，我们要保证读到这个存在脉冲，那么 60us 以后去读肯定可以读到。当然，不能延时太久，太久，超过 75us，就可能读不到了，为什么是 75us，大家自己思考一下。</p>
<h3 id="2-ROM-操作指令"><a href="#2-ROM-操作指令" class="headerlink" title="2) ROM 操作指令"></a>2) ROM 操作指令</h3><p>我们学 I2C 总线的时候就了解到，总线上可以挂多个器件，通过不同的器件地址来访问不同的器件。同样，1-Wire 总线也可以挂多个器件，但是它只有一条线，如何区分不同的器件呢？</p>
<p>在每个 DS18B20 内部都有一个唯一的 64 位长的序列号，这个序列号值就存在 DS18B20内部的 ROM 中。开始的 8 位是产品类型编码（DS18B20 是 0x10），接着的 48 位是每个器件唯一的序号，最后的 8 位是 CRC 校验码。DS18B20 可以引出去很长的线，最长可以到几十米，测不同位置的温度。单片机可以通过和 DS18B20 之间的通信，获取每个传感器所采集到的温度信息，也可以同时给所有的 DS18B20 发送一些指令。这些指令相对来说比较复杂，而且应用很少，所以这里大家有兴趣的话就自己去查手册完成吧，我们这里只讲一条总线上只接一个器件的指令和程序。</p>
<p>Skip ROM（跳过 ROM）：0xCC。当总线上只有一个器件的时候，可以跳过 ROM，不进行 ROM 检测。</p>
<h3 id="3-RAM-存储器操作指令"><a href="#3-RAM-存储器操作指令" class="headerlink" title="3) RAM 存储器操作指令"></a>3) RAM 存储器操作指令</h3><p>RAM 读取指令，只讲 2 条，其它的大家有需要可以随时去查资料。<br>Read Scratchpad（读暂存寄存器）：0xBE</p>
<p>这里要注意的是，DS18B20 的温度数据是 2 个字节，我们读取数据的时候，先读取到的是低字节的低位，读完了第一个字节后，再读高字节的低位，直到两个字节全部读取完毕。</p>
<p>Convert Temperature（启动温度转换）：0x44</p>
<p>当我们发送一个启动温度转换的指令后，DS18B20 开始进行转换。从转换开始到获取温度，DS18B20 是需要时间的，而这个时间长短取决于 DS18B20 的精度。前边说 DS18B20 最高可以用 12 位来存储温度，但是也可以用 11 位，10 位和 9 位一共四种格式。位数越高，精度越高，9 位模式最低位变化 1 个数字温度变化 0.5 度，同时转换速度也要快一些，如图 16-16所示。</p>
<p><img src="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323110U45.png" alt></p>
<center><strong>图 16-16  DS18B20 温度转换时间</strong></center>

<p>其中寄存器 R1 和 R0 决定了转换的位数，出厂默认值就 11，也就是 12 位表示温度，最大的转换时间是 750ms。当启动转换后，至少要再等 750ms 之后才能读取温度，否则读到的温度有可能是错误的值。这就是为什么很多同学读 DS18B20 的时候，第一次读出来的是 85度，这个值要么是没有启动转换，要么是启动转换了，但还没有等待一次转换彻底完成，读到的是一个错误的数据。</p>
<h3 id="4-DS18B20-的位读写时序"><a href="#4-DS18B20-的位读写时序" class="headerlink" title="4) DS18B20 的位读写时序"></a>4) DS18B20 的位读写时序</h3><p>DS18B20 的时序图不是很好理解，大家对照时序图，结合我的解释，一定要把它学明白。写时序图如图 16-17 所示。</p>
<p><img src="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323121O24.png" alt></p>
<center><strong>图 16-17  DS18B20 位写入时序</strong></center>

<p>当要给 DS18B20 写入 0 的时候，单片机直接将引脚拉低，持续时间大于 60us 小于 120us就可以了。图上显示的意思是，单片机先拉低 15us 之后，DS18B20 会在从 15us 到 60us 之间的时间来读取这一位，DS18B20 最早会在 15us 的时刻读取，典型值是在 30us 的时刻读取，最多不会超过 60us，DS18B20 必然读取完毕，所以持续时间超过 60us 即可。</p>
<p>当要给 DS18B20 写入 1 的时候，单片机先将这个引脚拉低，拉低时间大于 1us，然后马上释放总线，即拉高引脚，并且持续时间也要大于 60us。和写 0 类似的是，DS18B20 会在15us 到 60us 之间来读取这个 1。</p>
<p>可以看出来，DS18B20 的时序比较严格，写的过程中最好不要有中断打断，但是在两个“位”之间的间隔，是大于 1 小于无穷的，那在这个时间段，我们是可以开中断来处理其它程序的。发送即写入一个字节的数据程序如下。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">void Write18B20(unsigned char dat)&#123;</span><br><span class="line">    unsigned char mask;</span><br><span class="line">   </span><br><span class="line">    EA = 0; //禁止总中断</span><br><span class="line">    for (mask=0x01; mask!=0; mask&lt;&lt;=1)&#123; //低位在先，依次移出 8 个 bit</span><br><span class="line">        IO_18B20 = 0; //产生 2us 低电平脉冲</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        if ((mask&amp;dat) == 0)&#123; //输出该 bit 值</span><br><span class="line">            IO_18B20 = 0;</span><br><span class="line">        &#125;else&#123;</span><br><span class="line">            IO_18B20 = 1;</span><br><span class="line">        &#125;</span><br><span class="line">        DelayX10us(6); //延时 60us</span><br><span class="line">        IO_18B20 = 1; //拉高通信引脚</span><br><span class="line">    &#125;</span><br><span class="line">    EA = 1; //重新使能总中断</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>读时序图如图 16-18 所示。</p>
<p><img src="http://c.biancheng.net/cpp/uploads/allimg/140323/1-14032323163AN.png" alt></p>
<center><strong>图 16-18  DS18B20 位读取时序</strong></center>

<p>当要读取 DS18B20 的数据的时候，我们的单片机首先要拉低这个引脚，并且至少保持1us 的时间，然后释放引脚，释放完毕后要尽快读取。从拉低这个引脚到读取引脚状态，不能超过 15us。大家从图 16-18 可以看出来，主机采样时间，也就是 MASTER SAMPLES，是在 15us 之内必须完成的，读取一个字节数据的程序如下。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">unsigned char Read18B20(&#123;</span><br><span class="line">    unsigned char dat;</span><br><span class="line">    unsigned char mask;</span><br><span class="line">   </span><br><span class="line">    EA = 0; //禁止总中断</span><br><span class="line">    for (mask=0x01; mask!=0; mask&lt;&lt;=1)&#123; //低位在先，依次采集 8 个 bit</span><br><span class="line">        IO_18B20 = 0; //产生 2us 低电平脉冲</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        IO_18B20 = 1; //结束低电平脉冲，等待 18B20 输出数据</span><br><span class="line">        _nop_(); //延时 2us</span><br><span class="line">        _nop_();</span><br><span class="line">        if (!IO_18B20)&#123; //读取通信引脚上的值</span><br><span class="line">            dat &amp;= ~mask;</span><br><span class="line">        &#125;else&#123;</span><br><span class="line">            dat |= mask;</span><br><span class="line">        &#125;</span><br><span class="line">        DelayX10us(6); //再延时 60us</span><br><span class="line">    &#125;</span><br><span class="line">    EA = 1; //重新使能总中断</span><br><span class="line">    return dat;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>DS18B20 所表示的温度值中，有小数和整数两部分。常用的带小数的数据处理方法有两种，一种是定义成浮点型直接处理，第二种是定义成整型，然后把小数和整数部分分离出来，在合适的位置点上小数点即可。我们在程序中使用的是第二种方法，下面我们就写一个程序，将读到的温度值显示在 1602 液晶上，并且保留一位小数位。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br></pre></td><td class="code"><pre><span class="line">/***************************DS18B20.c 文件程序源代码****************************/</span><br><span class="line">#include &lt;reg52.h&gt;</span><br><span class="line">#include &lt;intrins.h&gt;</span><br><span class="line">sbit IO_18B20 = P3^2; //DS18B20 通信引脚</span><br><span class="line">/* 软件延时函数，延时时间(t*10)us */</span><br><span class="line">void DelayX10us(unsigned char t)&#123;</span><br><span class="line">    do &#123;</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">    &#125; while (--t);</span><br><span class="line">&#125;</span><br><span class="line">/* 复位总线，获取存在脉冲，以启动一次读写操作 */</span><br><span class="line">bit Get18B20Ack()&#123;</span><br><span class="line">    bit ack;</span><br><span class="line">    EA = 0; //禁止总中断</span><br><span class="line">    IO_18B20 = 0; //产生 500us 复位脉冲</span><br><span class="line">    DelayX10us(50);</span><br><span class="line">    IO_18B20 = 1;</span><br><span class="line">    DelayX10us(6); //延时 60us</span><br><span class="line">    ack = IO_18B20; //读取存在脉冲</span><br><span class="line">    while(!IO_18B20); //等待存在脉冲结束</span><br><span class="line">    EA = 1; //重新使能总中断</span><br><span class="line">    return ack;</span><br><span class="line">&#125;</span><br><span class="line">/* 向 DS18B20 写入一个字节，dat-待写入字节 */</span><br><span class="line">void Write18B20(unsigned char dat)&#123;</span><br><span class="line">    unsigned char mask;</span><br><span class="line">    EA = 0; //禁止总中断</span><br><span class="line">    for (mask=0x01; mask!=0; mask&lt;&lt;=1)&#123; //低位在先，依次移出 8 个 bit</span><br><span class="line">        IO_18B20 = 0; //产生 2us 低电平脉冲</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        if ((mask&amp;dat) == 0)&#123; //输出该 bit 值</span><br><span class="line">            IO_18B20 = 0;</span><br><span class="line">        &#125;else&#123;</span><br><span class="line">            IO_18B20 = 1;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    DelayX10us(6); //延时 60us</span><br><span class="line">    IO_18B20 = 1; //拉高通信引脚</span><br><span class="line">    EA = 1; //重新使能总中断</span><br><span class="line">&#125;</span><br><span class="line">/* 从 DS18B20 读取一个字节，返回值-读到的字节 */</span><br><span class="line">unsigned char Read18B20()&#123;</span><br><span class="line">    unsigned char dat;</span><br><span class="line">    unsigned char mask;</span><br><span class="line">    EA = 0; //禁止总中断</span><br><span class="line">    for (mask=0x01; mask!=0; mask&lt;&lt;=1)&#123; //低位在先，依次采集 8 个 bit</span><br><span class="line">        IO_18B20 = 0; //产生 2us 低电平脉冲</span><br><span class="line">        _nop_();</span><br><span class="line">        _nop_();</span><br><span class="line">        IO_18B20 = 1; //结束低电平脉冲，等待 18B20 输出数据</span><br><span class="line">        _nop_(); //延时 2us</span><br><span class="line">        _nop_();</span><br><span class="line">        if (!IO_18B20)&#123; //读取通信引脚上的值</span><br><span class="line">            dat &amp;= ~mask;</span><br><span class="line">        &#125;else&#123;</span><br><span class="line">            dat |= mask;</span><br><span class="line">        &#125;</span><br><span class="line">        DelayX10us(6); //再延时 60us</span><br><span class="line">    &#125;</span><br><span class="line">    EA = 1; //重新使能总中断</span><br><span class="line">    return dat;</span><br><span class="line">&#125;</span><br><span class="line">/* 启动一次 18B20 温度转换，返回值-表示是否启动成功 */</span><br><span class="line">bit Start18B20()&#123;</span><br><span class="line">    bit ack;</span><br><span class="line">    ack = Get18B20Ack(); //执行总线复位，并获取 18B20 应答</span><br><span class="line">    if (ack == 0)&#123; //如 18B20 正确应答，则启动一次转换</span><br><span class="line">        Write18B20(0xCC); //跳过 ROM 操作</span><br><span class="line">        Write18B20(0x44); //启动一次温度转换</span><br><span class="line">    &#125;</span><br><span class="line">    return ~ack; //ack==0 表示操作成功，所以返回值对其取反</span><br><span class="line">&#125;</span><br><span class="line">/* 读取 DS18B20 转换的温度值，返回值-表示是否读取成功 */</span><br><span class="line">bit Get18B20Temp(int *temp)&#123;</span><br><span class="line">    bit ack;</span><br><span class="line">    unsigned char LSB, MSB; //16bit 温度值的低字节和高字节</span><br><span class="line">    ack = Get18B20Ack(); //执行总线复位，并获取 18B20 应答</span><br><span class="line">    if (ack == 0)&#123; //如 18B20 正确应答，则读取温度值</span><br><span class="line">        Write18B20(0xCC); //跳过 ROM 操作</span><br><span class="line">        Write18B20(0xBE); //发送读命令</span><br><span class="line">        LSB = Read18B20(); //读温度值的低字节</span><br><span class="line">        MSB = Read18B20(); //读温度值的高字节</span><br><span class="line">        *temp = ((int)MSB &lt;&lt; 8) + LSB; //合成为 16bit 整型数</span><br><span class="line">    &#125;</span><br><span class="line">    return ~ack; //ack==0 表示操作应答，所以返回值为其取反值</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>/<strong><strong><strong><strong><strong><strong>***</strong></strong></strong></strong></strong></strong>Lcd1602.c 文件程序源代码<strong><strong><strong><strong><strong><strong><strong>*</strong></strong></strong></strong></strong></strong></strong>/</p>
<p>（此处省略，可参考之前章节的代码）</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br></pre></td><td class="code"><pre><span class="line">/*****************************main.c 文件程序源代码******************************/</span><br><span class="line">#include &lt;reg52.h&gt;</span><br><span class="line">bit flag1s = 0; //1s 定时标志</span><br><span class="line">unsigned char T0RH = 0; //T0 重载值的高字节</span><br><span class="line">unsigned char T0RL = 0; //T0 重载值的低字节</span><br><span class="line">void ConfigTimer0(unsigned int ms);</span><br><span class="line">unsigned char IntToString(unsigned char *str, int dat);</span><br><span class="line">extern bit Start18B20();</span><br><span class="line">extern bit Get18B20Temp(int *temp);</span><br><span class="line">extern void InitLcd1602();</span><br><span class="line">extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);</span><br><span class="line">void main()&#123;</span><br><span class="line">    bit res;</span><br><span class="line">    int temp; //读取到的当前温度值</span><br><span class="line">    int intT, decT; //温度值的整数和小数部分</span><br><span class="line">    unsigned char len;</span><br><span class="line">    unsigned char str[12];</span><br><span class="line">   </span><br><span class="line">    EA = 1; //开总中断</span><br><span class="line">    ConfigTimer0(10); //T0 定时 10ms</span><br><span class="line">    Start18B20(); //启动 DS18B20</span><br><span class="line">    InitLcd1602(); //初始化液晶</span><br><span class="line">   </span><br><span class="line">    while (1)&#123;</span><br><span class="line">        if (flag1s)&#123; //每秒更新一次温度</span><br><span class="line">            flag1s = 0;</span><br><span class="line">            res = Get18B20Temp(&amp;temp); //读取当前温度</span><br><span class="line">            if (res)&#123; //读取成功时，刷新当前温度显示</span><br><span class="line">                intT = temp &gt;&gt; 4; //分离出温度值整数部分</span><br><span class="line">                decT = temp &amp; 0xF; //分离出温度值小数部分</span><br><span class="line">                len = IntToString(str, intT); //整数部分转换为字符串</span><br><span class="line">                str[len++] = &apos;.&apos;; //添加小数点</span><br><span class="line">                decT = (decT*10) / 16; //二进制的小数部分转换为 1 位十进制位</span><br><span class="line">                str[len++] = decT + &apos;0&apos;; //十进制小数位再转换为 ASCII 字符</span><br><span class="line">                while (len &lt; 6)&#123; //用空格补齐到 6 个字符长度</span><br><span class="line">                    str[len++] = &apos; &apos;;</span><br><span class="line">                &#125;</span><br><span class="line">                str[len] = &apos;\0&apos;; //添加字符串结束符</span><br><span class="line">                LcdShowStr(0, 0, str); //显示到液晶屏上</span><br><span class="line">            &#125;else&#123; //读取失败时，提示错误信息</span><br><span class="line">                LcdShowStr(0, 0, &quot;error!&quot;);</span><br><span class="line">            &#125;</span><br><span class="line">            Start18B20(); //重新启动下一次转换</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">/* 整型数转换为字符串，str-字符串指针，dat-待转换数，返回值-字符串长度 */</span><br><span class="line">unsigned char IntToString(unsigned char *str, int dat)&#123;</span><br><span class="line">    signed char i = 0;</span><br><span class="line">    unsigned char len = 0;</span><br><span class="line">    unsigned char buf[6];</span><br><span class="line">   </span><br><span class="line">    if (dat &lt; 0)&#123; //如果为负数，首先取绝对值，并在指针上添加负号</span><br><span class="line">        dat = -dat;</span><br><span class="line">        *str++ = &apos;-&apos;;</span><br><span class="line">        len++;</span><br><span class="line">    &#125;</span><br><span class="line">    do &#123; //先转换为低位在前的十进制数组</span><br><span class="line">        buf[i++] = dat % 10;</span><br><span class="line">        dat /= 10;</span><br><span class="line">    &#125; while (dat &gt; 0);</span><br><span class="line">    len += i; //i 最后的值就是有效字符的个数</span><br><span class="line">    while (i-- &gt; 0)&#123; //将数组值转换为 ASCII 码反向拷贝到接收指针上</span><br><span class="line">        *str++ = buf[i] + &apos;0&apos;;</span><br><span class="line">    &#125;</span><br><span class="line">    *str = &apos;\0&apos;; //添加字符串结束符</span><br><span class="line">    return len; //返回字符串长度</span><br><span class="line">&#125;</span><br><span class="line">/* 配置并启动 T0，ms-T0 定时时间 */</span><br><span class="line">void ConfigTimer0(unsigned int ms)&#123;</span><br><span class="line">    unsigned long tmp; //临时变量</span><br><span class="line">    tmp = 11059200 / 12; //定时器计数频率</span><br><span class="line">    tmp = (tmp * ms) / 1000; //计算所需的计数值</span><br><span class="line">    tmp = 65536 - tmp; //计算定时器重载值</span><br><span class="line">    tmp = tmp + 12; //补偿中断响应延时造成的误差</span><br><span class="line">    T0RH = (unsigned char)(tmp&gt;&gt;8); //定时器重载值拆分为高低字节</span><br><span class="line">    T0RL = (unsigned char)tmp;</span><br><span class="line">    TMOD &amp;= 0xF0; //清零 T0 的控制位</span><br><span class="line">    TMOD |= 0x01; //配置 T0 为模式 1</span><br><span class="line">    TH0 = T0RH; //加载 T0 重载值</span><br><span class="line">    TL0 = T0RL;</span><br><span class="line">    ET0 = 1; //使能 T0 中断</span><br><span class="line">    TR0 = 1; //启动 T0</span><br><span class="line">&#125;</span><br><span class="line">/* T0 中断服务函数，完成 1 秒定时 */</span><br><span class="line">void InterruptTimer0() interrupt 1&#123;</span><br><span class="line">    static unsigned char tmr1s = 0;</span><br><span class="line">    TH0 = T0RH; //重新加载重载值</span><br><span class="line">    TL0 = T0RL;</span><br><span class="line">    tmr1s++;</span><br><span class="line">    if (tmr1s &gt;= 100)&#123; //定时 1s</span><br><span class="line">        tmr1s = 0;</span><br><span class="line">        flag1s = 1;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/limh/tags/教程/" rel="tag"># 教程</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/limh/2014/12/01/mcu108/" rel="next" title="16.3、NEC协议红外遥控器">
                <i class="fa fa-chevron-left"></i> 16.3、NEC协议红外遥控器
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/limh/2014/12/01/mcu110/" rel="prev" title="17.1、A/D和D/A的基本概念">
                17.1、A/D和D/A的基本概念 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      <div id="SOHUCS"></div>
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image" src="/limh/images/avatar.jpg" alt="土逗牛肉">
            
              <p class="site-author-name" itemprop="name">土逗牛肉</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/limh/archives/">
              
                  <span class="site-state-item-count">255</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/limh/categories/index.html">
                  <span class="site-state-item-count">8</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/limh/tags/index.html">
                  <span class="site-state-item-count">7</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/limhGeek" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-github"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="mailto:1591054297@qq.com" target="_blank" title="E-Mail">
                      
                        <i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://www.jianshu.com/u/f73b243e7cc9" target="_blank" title="简书">
                      
                        <i class="fa fa-fw fa-user-circle-o"></i>简书</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-初始化"><span class="nav-number">1.</span> <span class="nav-text">1) 初始化</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-ROM-操作指令"><span class="nav-number">2.</span> <span class="nav-text">2) ROM 操作指令</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-RAM-存储器操作指令"><span class="nav-number">3.</span> <span class="nav-text">3) RAM 存储器操作指令</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-DS18B20-的位读写时序"><span class="nav-number">4.</span> <span class="nav-text">4) DS18B20 的位读写时序</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2019</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">土逗牛肉</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Gemini</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
	var str = GetUrlParam('height');
    if (str === '0'){
		document.getElementById('header').style.display = 'none';
		document.getElementById('comments').style.display = 'none';
		document.getElementById('footer').style.display = 'none';
		document.getElementsByClassName('post-footer').item(0).style.display = 'none'
	}
	
    function GetUrlParam(paraName) {
        var url = document.location.toString();
        var arrObj = url.split("?");

        if (arrObj.length > 1) {
            var arrPara = arrObj[1].split("&");
            var arr;

            for (var i = 0; i < arrPara.length; i++) {
                 arr = arrPara[i].split("=");

                if (arr != null && arr[0] === paraName) {
                    return arr[1];
                }
            }
            return "";
        } else {
            return "";
        }
    }
</script>









  












  
  
    <script type="text/javascript" src="/limh/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/limh/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/limh/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/limh/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/limh/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/limh/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/limh/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/limh/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
